/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sym.qrcode.style;

import java.awt.Color;
import java.awt.image.BufferedImage;

import sym.qrcode.encoder.ByteMatrix;
import sym.qrcode.encoder.Mosaic;
import sym.qrcode.encoder.MosaicMatrix;
import sym.qrcode.image.ImageMosaicMatrix;
import sym.qrcode.image.OutputImage;
/**
 *
 * @author zhanqxun
 */
public class EditStyle implements ImageGenerator{
     public static final int MARGIN = 2;
    private OutputImage outputMatrix;


    public EditStyle(OutputImage outputImage) {
        this.outputMatrix = outputImage;

    }



    @Override
    public BufferedImage getFinalImage() {
        // TODO Auto-generated method stub
        MosaicMatrix m = outputMatrix.getQrcode().getMosaicMatrix();
        ByteMatrix matrix = outputMatrix.getQrcode().getMatrix();
        int scale = outputMatrix.getScale();
        int negtiveWidth = outputMatrix.getNegtiveImageWidth();
        int negtiveHeight = outputMatrix.getNegtiveImageHeight();
        BufferedImage resultImage = new BufferedImage(2 * MARGIN * scale
                + outputMatrix.getMaxImageWidth() + negtiveWidth, 2 * MARGIN
                * scale + outputMatrix.getMaxImageHeight() + negtiveHeight,
                BufferedImage.TYPE_INT_RGB);
        for (int p = 0; p < resultImage.getWidth(); p++) {
            for (int q = 0; q < resultImage.getHeight(); q++) {
                resultImage.setRGB(p, q, Color.white.getRGB());
            }
        }
        for (int i = 0; i < m.getWidth(); i++) {
            for (int j = 0; j < m.getHeight(); j++) {
                Mosaic mosaic = m.get(i, j);
                if (!isImage(i, j)) {
                    if ((matrix.get(i, j) != 0&&!mosaic.isIsReverse())||
                           (matrix.get(i, j) == 0&&mosaic.isIsReverse()) ) {
                        
                        for (int p = 0; p < scale; p++) {
                            for (int q = 0; q < scale; q++) {
                                if (m.getMosaics()[j][i].type == Mosaic.CRUCIALFUNC
                                        && m.getMosaics()[j][i].func_type == Mosaic.FIND_PATTERN_CENTER) {
                                    resultImage.setRGB(MARGIN * scale + i * scale
                                            + negtiveWidth + p, MARGIN * scale + j
                                            * scale + negtiveHeight + q,
                                            mosaic.getColor().getRGB());
                                } else if (m.getMosaics()[j][i].type == Mosaic.CRUCIALFUNC
                                        && m.getMosaics()[j][i].func_type == Mosaic.FIND_PATTERN_OUTER) {
                                    resultImage.setRGB(MARGIN * scale + i * scale
                                            + negtiveWidth + p, MARGIN * scale + j
                                            * scale + negtiveHeight + q,
                                            mosaic.getColor().getRGB());
                                } else {
                                    resultImage.setRGB(MARGIN * scale + i * scale
                                            + negtiveWidth + p, MARGIN * scale + j
                                            * scale + negtiveHeight + q,
                                            mosaic.getColor().getRGB());
                                }
                            }
                        }
                    }
                }
            }
        }
        for (ImageMosaicMatrix m2 : outputMatrix.getMosaicList()) {
            for (int i2 = 0; i2 < m2.getWidth(); i2++) {
                for (int j2 = 0; j2 < m2.getHeight(); j2++) {
                    if (m2.getMatrix()[j2][i2].type == Mosaic.IMAGE) {
                        for (int p = 0; p < scale; p++) {
                            for (int q = 0; q < scale; q++) {
                                if (!isWhite(new Color(m2.getColorRGB(i2
                                        * scale + p, j2 * scale + q)))) {
                                    resultImage.setRGB(MARGIN * scale
                                            + (m2.getX() + i2) * scale
                                            + negtiveWidth + p,
                                            MARGIN * scale
                                            + (m2.getY() + j2)
                                            * scale
                                            + negtiveHeight + q,
                                            m2.getColorRGB(i2 * scale
                                            + p, j2 * scale + q));
                                } else {
                                    resultImage.setRGB(MARGIN * scale
                                            + (m2.getX() + i2) * scale
                                            + negtiveWidth + p,
                                            MARGIN * scale
                                            + (m2.getY() + j2)
                                            * scale
                                            + negtiveHeight + q,
                                            Color.white.getRGB());
                                }
                            }
                        }
                    }
                }
            }
        }
        return resultImage;
    }
     private boolean isWhite(Color color) {
        // TODO Auto-generated method stub
        if (color.getRed() > WHITETHRESHOLD && color.getBlue() > WHITETHRESHOLD
                && color.getGreen() > WHITETHRESHOLD) {
            return true;
        }
        return false;
    }

    protected boolean isImage(int i, int j) {
        // TODO Auto-generated method stub

        for (ImageMosaicMatrix m2 : outputMatrix.getMosaicList()) {
            if (j - m2.getY() >= 0 && j - m2.getY() < m2.getHeight()
                    && i - m2.getX() >= 0 && i - m2.getX() < m2.getWidth()) {
                if (m2.getMatrix()[j - m2.getY()][i - m2.getX()].type == Mosaic.IMAGE) {
                    return true;

                }
            }
        }
        return false;
    }
}
